package org.ragdollcat.first.controller;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.ragdollcat.first.api.ai.aliyun.model.CreateOutPaintingTaskResponse;
import org.ragdollcat.first.api.ai.aliyun.model.GetOutPaintingTaskResponse;
import org.ragdollcat.first.api.search.baidu.GetImageFacade;
import org.ragdollcat.first.api.search.baidu.ImageSearchResult;
import org.ragdollcat.first.manager.auth.SaSpaceCheckPermission;
import org.ragdollcat.first.manager.auth.SpaceUserAuthManager;
import org.ragdollcat.first.manager.auth.StpKit;
import org.ragdollcat.first.common.BaseResponse;
import org.ragdollcat.first.common.DeleteRequest;
import org.ragdollcat.first.common.ResultUtils;
import org.ragdollcat.first.constants.SpaceUserPermissionConstant;
import org.ragdollcat.first.constants.UserConstant;
import org.ragdollcat.first.exception.ErrorCode;
import org.ragdollcat.first.exception.ThrowUtils;
import org.ragdollcat.first.model.annotation.AuthCheck;
import org.ragdollcat.first.model.dto.picture.*;
import org.ragdollcat.first.model.entity.Picture;
import org.ragdollcat.first.model.entity.Space;
import org.ragdollcat.first.model.entity.User;
import org.ragdollcat.first.model.enums.PictureReviewStatusEnum;
import org.ragdollcat.first.model.vo.PictureVO;
import org.ragdollcat.first.service.PictureService;
import org.ragdollcat.first.service.SpaceService;
import org.ragdollcat.first.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/picture")
@Slf4j
public class FileController {

    @Resource
    private PictureService pictureService;

    @Resource
    private UserService userService;

    @Resource
    private SpaceService spaceService;

    @Resource
    private SpaceUserAuthManager spaceUserAuthManager;

    /**
     * 管理员或用户上传文件接口
     *
     * @param multipartFile
     * @param pictureUploadRequest
     * @param httpServletRequest
     * @return
     */
//    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/upload")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_UPLOAD)
    public BaseResponse<PictureVO> uploadPicture(@RequestPart("multipartFile") MultipartFile multipartFile,
                                                 PictureUploadRequest pictureUploadRequest,
                                                 HttpServletRequest httpServletRequest) {
        return ResultUtils.success(pictureService.uploadPicture(multipartFile, pictureUploadRequest, userService.getLoginUser(httpServletRequest)));
    }


    /**
     * 管理员或用户根据url上传图片接口
     *
     * @param pictureUploadRequest
     * @param httpServletRequest
     * @return
     */
//    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/urlUpload")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_UPLOAD)
    public BaseResponse<PictureVO> urlUploadPicture(
            @RequestBody PictureUploadRequest pictureUploadRequest,
            HttpServletRequest httpServletRequest) {
        return ResultUtils.success(pictureService.uploadPicture(pictureUploadRequest.getUrl(), pictureUploadRequest, userService.getLoginUser(httpServletRequest)));
    }


    /**
     * 根据ID删除图片，用于公共图库详情页，私有图库，图片管理
     * 如果是公共图库：
     * 管理员可以删除所有，用户只能删除自己的
     * 图片管理页面仅仅对管理员开放，可以删除所有
     * 私有图库：只有用户自身才能操作
     *
     * @param deleteRequest
     * @return
     */
    @PostMapping("/deleteById")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_DELETE)
    public BaseResponse<Boolean> deletePicById(@RequestBody DeleteRequest deleteRequest, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(deleteRequest), ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(pictureService.deletePicById(deleteRequest, httpServletRequest));
    }


    /**
     * 管理员更新图片
     *
     * @param pictureUpdateRequest
     * @return
     */
    @PostMapping("/admin/updatePic")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> adminUpdatePic(@RequestBody PictureUpdateRequest pictureUpdateRequest, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureUpdateRequest), ErrorCode.PARAMS_ERROR);
        //校验要修改的图片是否存在
        Long id = pictureUpdateRequest.getId();
        Picture pic = pictureService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isEmpty(pic), ErrorCode.OPERATION_ERROR, "该图片不存在！");
        //更新参数校验
        pictureService.vaildUpdPicParam(pictureUpdateRequest);
        //更新图片
        Picture picture = new Picture();
        BeanUtils.copyProperties(pictureUpdateRequest, picture);
        //tag需要从List转成JSON字符串
        picture.setTags(JSONUtil.toJsonStr(pictureUpdateRequest.getTags()));
        //填充审批参数
        pictureService.fillCheckParams(picture, userService.getLoginUser(httpServletRequest), true);
        ThrowUtils.throwIf(!pictureService.updateById(picture), ErrorCode.OPERATION_ERROR, "图片更新失败！");
        return ResultUtils.success(true);
    }

    /**
     * 管理员分页获取图片列表，不需要脱敏
     * 展示所有图片，无论是否审批通过，用于图片管理页面
     *
     * @param pictureQueryRequest
     * @return
     */
    @PostMapping("/admin/picPage")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Picture>> adminPicPage(@RequestBody PictureQueryRequest pictureQueryRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureQueryRequest), ErrorCode.PARAMS_ERROR);
//        int pageSize = pictureQueryRequest.getPageSize();
//        ThrowUtils.throwIf(pageSize > 20,ErrorCode.PARAMS_ERROR,"单次查询图片大小不能大于20张");
        //管理员只能看到公共图库
        pictureQueryRequest.setNullSpaceId(true);
        return ResultUtils.success(pictureService.getPicPage(pictureQueryRequest));
    }

    /**
     * 管理员根据ID获取图片，不需要脱敏
     *
     * @param id
     * @return
     */
    @GetMapping("/admin/getPicById")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Picture> adminGetPicById(Long id) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(id), ErrorCode.PARAMS_ERROR);
        Picture pic = pictureService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isEmpty(pic), ErrorCode.OPERATION_ERROR, "未查询到图片！");
        return ResultUtils.success(pic);
    }

    /**
     * 分页获取图片列表，需要脱敏，限制条数
     * 用于主页和空间展示，主页只展示审核通过的图片
     * 如果是空间给用户展示，不涉及审核
     *
     * @param pictureQueryRequest
     * @return
     */
    @PostMapping("/user/picPage")
    public BaseResponse<Page<PictureVO>> userPicPage(@RequestBody PictureQueryRequest pictureQueryRequest, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureQueryRequest), ErrorCode.PARAMS_ERROR);
        int pageSize = pictureQueryRequest.getPageSize();
        ThrowUtils.throwIf(pageSize > 20, ErrorCode.PARAMS_ERROR, "当前最多查询20张图片！");
        Long spaceId = pictureQueryRequest.getSpaceId();
        //根据spaceId判断是公共还是私有图库
        if (spaceId == null) {
            pictureQueryRequest.setNullSpaceId(true);
            //只展示审核通过的图片
            pictureQueryRequest.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());
        } else {
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(ObjUtil.isEmpty(space), ErrorCode.OPERATION_ERROR, "空间不存在");
            //编程式权限校验
            ThrowUtils.throwIf(!StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_VIEW), ErrorCode.NO_AUTH_ERROR);
//
//            ThrowUtils.throwIf(!userService.getLoginUser(httpServletRequest).getId().equals(space.getUserId()),
//                    ErrorCode.NO_AUTH_ERROR, "无权查看！");
        }
        return ResultUtils.success(pictureService.getPicPageVO(pictureQueryRequest));
    }

    /**
     * 用户根据ID获取脱敏后的图片
     * 用于图片详情页
     *
     * @param id
     * @return
     */
    @GetMapping("/user/getPageById")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_VIEW)
    public BaseResponse<PictureVO> userGetPicById(Long id, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(id), ErrorCode.PARAMS_ERROR);
        Picture pic = pictureService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isEmpty(pic), ErrorCode.OPERATION_ERROR, "未查询到图片！");
        //空间的图片需要校验权限
        Long spaceId = pic.getSpaceId();
        if (spaceId != null) {
            ThrowUtils.throwIf(!StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_VIEW), ErrorCode.NO_AUTH_ERROR);
        }
//        pictureService.vaildPictureAuth(pic, httpServletRequest);
        //脱敏
        PictureVO pictureVO = pictureService.castPicToPicVO(pic);
        pictureVO.setPremissionList(spaceUserAuthManager.getPermissionList(spaceService.getById(spaceId),userService.getLoginUser(httpServletRequest)));
        return ResultUtils.success(pictureVO);
    }

    /**
     * 管理员或用户修改图片
     *
     * @param pictureUpdateRequest
     * @return
     */
    @PostMapping("/user/updatePic")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_EDIT)
    public BaseResponse<Boolean> userUpdatePic(@RequestBody PictureUpdateRequest pictureUpdateRequest, HttpServletRequest httpServletRequest
    ) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureUpdateRequest), ErrorCode.PARAMS_ERROR);

        //校验要修改的图片是否存在
        Long id = pictureUpdateRequest.getId();
        Picture pic = pictureService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isEmpty(pic), ErrorCode.OPERATION_ERROR, "该图片不存在！");
        //校验权限
        //私有图库，只有用户自身可以操作，公共图库，管理员和用户自身都可以操作
//        pictureService.vaildPictureAuth(pic, httpServletRequest);
        //更新参数校验
        pictureService.vaildUpdPicParam(pictureUpdateRequest);
        //更新图片
        Picture picture = new Picture();
        BeanUtils.copyProperties(pictureUpdateRequest, picture);
        //tag需要从List转成JSON字符串
        picture.setTags(JSONUtil.toJsonStr(pictureUpdateRequest.getTags()));
        //填充审批参数
        pictureService.fillCheckParams(picture, userService.getLoginUser(httpServletRequest), true);
        ThrowUtils.throwIf(!pictureService.updateById(picture), ErrorCode.OPERATION_ERROR, "图片更新失败！");
        return ResultUtils.success(true);
    }


    @GetMapping("/tag_category")
    public BaseResponse<PictureTagCategory> listPictureTagCategory() {
        PictureTagCategory pictureTagCategory = new PictureTagCategory();
        List<String> tagList = Arrays.asList("热门", "搞笑", "生活", "高清", "艺术", "校园", "背景", "简历", "创意");
        List<String> categoryList = Arrays.asList("模板", "电商", "表情包", "素材", "海报");
        pictureTagCategory.setTagList(tagList);
        pictureTagCategory.setCategoryList(categoryList);
        return ResultUtils.success(pictureTagCategory);
    }

    /**
     * 管理员审批图片
     *
     * @param pictureReviewRequest
     * @return
     */
    @PostMapping("/admin/approve/Picture")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> adminApprovePicture(PictureReviewRequest pictureReviewRequest, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureReviewRequest), ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(pictureService.adminApprovePicture(pictureReviewRequest, httpServletRequest));
    }

    /**
     * 管理员批量抓取图片
     *
     * @param pictureUploadByBatchRequest
     * @return
     */
    @PostMapping("/admin/fetchPic")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Integer> adminFetchPicture(@RequestBody PictureUploadByBatchRequest pictureUploadByBatchRequest, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureUploadByBatchRequest), ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(pictureService.adminFetchPicture(pictureUploadByBatchRequest, httpServletRequest));
    }

    /**
     * 以图搜图
     *
     * @param id 图片ID
     * @return
     */
    @GetMapping("/searchPicByPic")
    public BaseResponse<List<ImageSearchResult>> searchPicByPic(Long id) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(id), ErrorCode.PARAMS_ERROR);
        Picture picture = pictureService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isEmpty(picture), ErrorCode.OPERATION_ERROR, "根据ID未查询到图片");
        //用缩略图去搜图，防止webp格式图片搜索失败
        String thumbnailUrl = picture.getThumbnailUrl();
        return ResultUtils.success(GetImageFacade.getImages(thumbnailUrl));
    }

    /**
     * 根据颜色搜图
     *
     * @param searchPictureByColorRequest 图片空间 图片颜色值
     * @param httpServletRequest          用于获取用户登录信息
     * @return
     */
    @PostMapping("/searchPicByColor")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_VIEW)
    public BaseResponse<List<PictureVO>> searchPicByColor(SearchPictureByColorRequest searchPictureByColorRequest,
                                                          HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(searchPictureByColorRequest), ErrorCode.PARAMS_ERROR);
        User loginUser = userService.getLoginUser(httpServletRequest);
        ThrowUtils.throwIf(ObjUtil.isEmpty(loginUser), ErrorCode.OPERATION_ERROR, "请先登录");
        return ResultUtils.success(pictureService.searchPicByColor(searchPictureByColorRequest, loginUser));
    }

    /**
     * 用户批量更新图片信息
     *
     * @param pictureEditByBatchRequest
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/user/batch/updatePic")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_EDIT)
    public BaseResponse<Boolean> batchUserUpdatePic(@RequestBody PictureEditByBatchRequest pictureEditByBatchRequest, HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureEditByBatchRequest), ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(pictureService.batchUserUpdatePic(pictureEditByBatchRequest, httpServletRequest));
    }

    /**
     * 创建AI处理图片任务
     *
     * @param createPictureOutPaintingTaskRequest
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/create/PicHandletask")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_EDIT)
    public BaseResponse<CreateOutPaintingTaskResponse> createPicHandletask(@RequestBody CreatePictureOutPaintingTaskRequest createPictureOutPaintingTaskRequest,
                                                                           HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(createPictureOutPaintingTaskRequest), ErrorCode.PARAMS_ERROR, "请求参数为空");
        return ResultUtils.success(pictureService.createPicHandletask(createPictureOutPaintingTaskRequest, httpServletRequest));
    }


    /**
     * 查询AI处理图片任务结果
     *
     * @param taskId
     * @return
     */
    @GetMapping("/query/PicHandletask")
    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_EDIT)
    public BaseResponse<GetOutPaintingTaskResponse> queryPicHandletask(String taskId) {
        ThrowUtils.throwIf(StrUtil.isBlank(taskId), ErrorCode.PARAMS_ERROR, "请求参数为空");
        return ResultUtils.success(pictureService.queryPicHandletask(taskId));
    }

}
